package com.baseweb.webadmin.controller.app;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.baseweb.webadmin.alipay.config.AlipayConfig;
import com.baseweb.webadmin.alipay.util.AlipayParams;
import com.baseweb.webadmin.alipay.util.AlipaySubmit;
import com.baseweb.webadmin.controller.BaseController;
import com.baseweb.webadmin.core.constants.*;
import com.baseweb.webadmin.core.model.pojo.*;
import com.baseweb.webadmin.core.util.*;
import com.baseweb.webadmin.service.UserOrderService;
import com.baseweb.webadmin.service.UserService;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * Created by zhouxin on 2017/8/22.
 */
@Controller
@RequestMapping(value = "/appApiPay")
public class PayAppController  extends BaseController {

    private Logger logger = LoggerFactory.getLogger(PayAppController.class);

    @Autowired
    private UserOrderService userOrderService;

    @Autowired
    private UserService userService;

    /**
     * 支付生成订单
     * @throws IOException
     */
    @RequestMapping(value="/orderPay",method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> ordersPay(
            @RequestParam(value = "product_id",required = true) Integer product_id,
            @RequestParam(value = "userId",required = true) Integer userId,
            @RequestParam(value = "biz_user_id",required = true) Integer biz_user_id,
            @RequestParam(value = "schedule_date",required = true) String schedule_date,
            @RequestParam(value = "dinner_type",required = true) String dinner_type,
            @RequestParam(value = "num",defaultValue = "1") Integer qty_item_1,
            @RequestParam(value = "descn",required = false) String descn,
            @RequestParam(value = "pay_status",defaultValue = "2") Integer pay_status,
            @RequestParam(value = "payFor",required = false) String payFor) throws IOException{

        ByUserOrder order = new ByUserOrder();
        if (product_id != null && product_id > 0) {
            ByUserBizProduct byUserBizProduct = userService.findBizProduct(product_id);
            User currentBizUser = userService.selectUserById(biz_user_id);

            order.setUserId(userId);

            order.setPayType(PayType.ALIPAY.getCode());
            order.setPayStatus(OrderPayStatus.NOT_PAY.getCode());
            order.setBizUserId(biz_user_id);
            order.setDescn(descn);
            order.setCreateTime(new DateTime());
            order.setUpdateTime(new DateTime());

            BigDecimal orderPrice = BigDecimal.ZERO;


            //更新订单价格
            if(qty_item_1 == null || qty_item_1 < 1){
                qty_item_1 = 1;
            }

            order.setPrice(byUserBizProduct.getCurrentPrice().multiply(new BigDecimal(qty_item_1)));
//            if (currentBizUser.getBizWorkType().intValue() == 1){ //策划师
//                order.setStatus(OrderStatus.NEW_ORDER.getCode());
//            }else{
            order.setStatus(OrderStatus.VERIFY_ORDER.getCode());
            //   }
            BigDecimal per = byUserBizProduct.getDeposit() == null ? new BigDecimal("0") : byUserBizProduct.getDeposit().divide(new BigDecimal("100"));
            if (pay_status.intValue() == OrderPayStatus.PAY_ALL.getCode()) {
                order.setDeposit(order.getPrice());
                order.setNeedPayPrice(BigDecimal.ZERO);
            }else{

                order.setDeposit(per.multiply(order.getPrice()));
                order.setNeedPayPrice(order.getPrice().subtract(order.getDeposit()));
            }

            userOrderService.insertByUserOrder(order);


            //insert order detail

            ByUserOrderDetail detail = new ByUserOrderDetail();
            detail.setOrderId(order.getId());
            detail.setUserId(userId);
            detail.setProductId(product_id);
            detail.setAmount(qty_item_1);
            detail.setPrice(order.getPrice());

            detail.setScheduleDate(DateUtil.getDateTime(schedule_date));
            detail.setDinnerType(dinner_type);
            detail.setBizUserId(byUserBizProduct.getUserId());
            detail.setOrderId(order.getId());
            detail.setDeposit(per.multiply(detail.getPrice()));
//            detail.setDeposit(Constants.PRODUCT_DEPOSIT_RATIO.multiply(detail.getPrice()));
            detail.setCreateTime(new DateTime());
            detail.setUpdateTime(new DateTime());
            userOrderService.insertByUserOrderDetail(detail);

            //add Schedule
            ByUserBizSchedule byUserBizSchedule = new ByUserBizSchedule();
            byUserBizSchedule.setUserId(biz_user_id);
            byUserBizSchedule.setScheduleDate(detail.getScheduleDate());
            byUserBizSchedule.setStatus(BaseState.NORMAL.getCode());
            byUserBizSchedule.setScheduleType(ScheduleType.getByName(detail.getDinnerType()).getCode());
            byUserBizSchedule.setOrderBy(detail.getUserId());
            byUserBizSchedule.setCreateTime(new DateTime());
            byUserBizSchedule.setUpdateTime(new DateTime());

            userOrderService.insertSchedule(byUserBizSchedule);

        }

        String payParam = userOrderService.ordersPay(order.getId()+"",userId,pay_status,payFor);
        Map<String,String> map = new HashMap<>();
        map.put("payParam",payParam);
        return  success(payParam,"支付订单生成");
    }


    /**
     * 支付请求回调
     * 获取支付宝POST过来反馈信息
     * params
     * requestMap:支付宝回调的request.getParameterMap
     * */
    @RequestMapping(value="/payNotify")
    @ResponseBody
    public boolean aliPayRequestParams(HttpServletRequest request, HttpServletResponse response){
        logger.info("APP 支付回调============================================");
        Map<String,String> params= AlipayParams.getAlipayParamsForMap(request);
        try {
            //验证签名
            //切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
            boolean flag = AlipaySignature.rsaCheckV1(params, AlipayConfig.app_public_key, AlipayConfig.input_charset, AlipayConfig.app_sign_type);
            logger.info("APP 支付回调，验证结果============================================" + flag);
            if(flag){
                logger.info("APP 支付回调，验证结果============================================TRADE_SUCCESS：" + params.get("trade_status"));
                if("TRADE_SUCCESS".equals(params.get("trade_status"))){
//                    //付款金额
//                    String amount = params.get("buyer_pay_amount");
//                    //商户订单号
                    String orderNum = params.get("out_trade_no");
//                    //支付宝交易号
//                    String trade_no = params.get("trade_no");
//                    //附加数据
//                    String passback_params = URLDecoder.decode(params.get("passback_params"));
                    logger.info("APP 支付回调，验证结果============================================orderNum：" + orderNum);
                    if (!CitiesUtil.isNumeric(orderNum) && orderNum.indexOf("bt-") != -1 && orderNum.substring(0,3).equalsIgnoreCase("bt-")){
                        //批量支付
                        ByUserBatchPayOrder batchPayOrder = userOrderService.findByUserBatchPayOrderByNum(orderNum);

                        String orderIds[] = batchPayOrder.getOrderIds().split(",");
                        Integer userId = null;

                        if (orderIds != null && orderIds.length > 0) {
                            List<Integer> orderIdList = new ArrayList<Integer>();
                            List<Integer> bizUserIdList = new ArrayList<Integer>();
                            for (int i = 0; i < orderIds.length; i++) {
                                orderIdList.add(Integer.valueOf(orderIds[i]));
                            }
                            List<ByUserOrder> orderList = userOrderService.findByUserOrderList(orderIdList);

                            for (ByUserOrder current : orderList) {
                                current.setPayType(Const.OrdersPayMethod.ALIPAY);
                                current.setPayStatus(batchPayOrder.getPriceType());
//                            orders.setNeedPayPrice(oldOrder.getPrice().subtract(orders.getAlipaytotalfee()));
                                userOrderService.insertByUserOrder(current);
                                userId = current.getUserId();
                                bizUserIdList.add(current.getBizUserId());
                                ByMoneyLog byMoneyLog = new ByMoneyLog();
                                byMoneyLog.setUserId(current.getBizUserId());
                                byMoneyLog.setMoneyType(1);
                                if (batchPayOrder.getPriceType().intValue() == OrderPayStatus.PAY_ALL.getCode()){
                                    byMoneyLog.setAmount(current.getPrice());
                                }else{
                                    byMoneyLog.setAmount(current.getDeposit());
                                }
                                byMoneyLog.setCreateTime(new DateTime());
                                userService.insertSelectiveByMoneyLog(byMoneyLog);
                            }
                            User payUser = userService.selectUserById(userId);
                            List<User> bizUserList = new ArrayList<User>();
                            if (bizUserIdList != null && bizUserIdList.size() > 0){
                                bizUserList = userService.selectUserByIds(bizUserIdList);
                                for(User biz : bizUserList){
                                    //send msg
                                    Map<String, Object> map = new LinkedHashMap<String, Object>();
                                    map.put("code", ""+biz.getId());

                                    if (biz != null && StringUtils.isNotBlank(biz.getMobile()) && biz.getBizWorkType() != null) {
                                        CommonUtil.sendMessage(biz.getMobile(), JSONObject
                                                .fromObject(map).toString(), ConfigUtil
                                                .getSms_template_code_new_order());
                                        String content = (payUser != null ? payUser.getCnName() : "") + "已付款，请及时接单";
                                        ByUserMessage userMessage = new ByUserMessage();
                                        userMessage.setCreateTime(new DateTime(Calendar.getInstance()));
                                        userMessage.setContent(content);
                                        userMessage.setUserId(biz.getId());
                                        userService.insertUserMessage(userMessage);
                                    }
                                }
                            }

                        }
                    }else{
                        logger.info("APP 支付回调，验证结果,pay only one============================================");
                        ByUserOrder byUserOrder = userOrderService.findByUserOrder(Integer.valueOf(orderNum));
                        //单个支付
                        byUserOrder = AlipayParams.getAlipayParamsForOrder(byUserOrder, params);
                        byUserOrder.setPayType(Const.OrdersPayMethod.ALIPAY);
                        ByMoneyLog byMoneyLog = new ByMoneyLog();
                        byMoneyLog.setUserId(byUserOrder.getBizUserId());
                        byMoneyLog.setMoneyType(1);
                        byMoneyLog.setCreateTime(new DateTime());
                        User payUser = userService.selectUserById(byUserOrder.getUserId());
                        byUserOrder.setNeedPayPrice(byUserOrder.getPrice().subtract(byUserOrder.getAlipaytotalfee()));
                        if (byUserOrder.getPrice().compareTo(byUserOrder.getAlipaytotalfee()) == 0){
                            byUserOrder.setPayStatus(OrderPayStatus.PAY_ALL.getCode());
                            byMoneyLog.setAmount(byUserOrder.getPrice());
                        }else {
                            byUserOrder.setPayStatus(OrderPayStatus.PAY_DEPOSIT.getCode());
                            byMoneyLog.setAmount(byUserOrder.getDeposit());
                        }

                        userOrderService.insertByUserOrder(byUserOrder);
                        userService.insertSelectiveByMoneyLog(byMoneyLog);
                        //send msg
                        Map<String, Object> map = new LinkedHashMap<String, Object>();
                        map.put("code", ""+byUserOrder.getStatus());

                        User bizUser = userService.selectUserById(byUserOrder.getBizUserId());
                        if (bizUser != null && StringUtils.isNotBlank(bizUser.getMobile()) && bizUser.getBizWorkType() != null){
                            if (bizUser != null && StringUtils.isNotBlank(bizUser.getMobile())) {
                                CommonUtil.sendMessage(bizUser.getMobile(), JSONObject
                                        .fromObject(map).toString(), ConfigUtil
                                        .getSms_template_code_new_order());
                                String content = (payUser != null ? payUser.getCnName() : "") + "已付款，请及时接单";
                                ByUserMessage userMessage = new ByUserMessage();
                                userMessage.setCreateTime(new DateTime(Calendar.getInstance()));
                                userMessage.setContent(content);
                                userMessage.setUserId(bizUser.getId());
                                userService.insertUserMessage(userMessage);
                            }
                        }

                    }
                }
            }
            return flag;
        }catch (AlipayApiException e) {
            e.printStackTrace();
            return false;
        }
    }
}
